package com.sinodata.bsm.cicp.collector.weblogic9;

import java.util.ArrayList;
import java.util.List;

import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;

import org.apache.log4j.Logger;

import com.sinodata.bsm.cicp.collector.Collector;
import com.sinodata.bsm.cicp.exception.CollectorException;
import com.sinodata.bsm.cicp.util.JmxUtil;
import com.sinodata.bsm.common.vo.ResPropertyValue;

/**
 * 
 * <p>
 * Description: WebLogic9 JDBC数据库源采集器
 * </p>
 *
 * @author liulibo
 * @version 3.1

 * <p>
 * History: 
 *
 * Date                     Author         Version     Description
 * ---------------------------------------------------------------------------------
 * Jun 22, 2011 4:30:00 PM  liulibo        3.1.0       To create
 * </p>
 *
 * @since 
 * @see
 */
public class JdbcCollector extends Collector {

    private static final Logger logger = Logger.getLogger(ServerSecurityCollector.class);

    @Override
    public List<ResPropertyValue> collect(String ip) throws CollectorException {
        List<ResPropertyValue> values = new ArrayList<ResPropertyValue>();
        String[] propMetas = getPropMeta();
        ResPropertyValue propertyValueX = new ResPropertyValue();
        ResPropertyValue.PropValue[] propValues = new ResPropertyValue.PropValue[propMetas.length];
        String serversName = this.getParamMap().get("ServerName").trim();
        String jdbcName = this.getParamMap().get("JDBCName").trim();
        String port = this.getParamMap().get("port").trim();
        ObjectName service;
        String name = null;
        JMXConnector connector = null;
        MBeanServerConnection connection = null;
        try {
            connector = JmxUtil.getConnection(ip, Integer.parseInt(port));
            connection = connector.getMBeanServerConnection();
            service = new ObjectName("com.bea:Name=DomainRuntimeService,Type=weblogic.management.mbeanservers.domainruntime.DomainRuntimeServiceMBean");
            ObjectName[] serverRuntimes = (ObjectName[]) connection.getAttribute(service, "ServerRuntimes");
            for (ObjectName objectName2 : serverRuntimes) {
                String serverName1 = objectName2.getKeyProperty("Name");
                if (serverName1.equals(serversName)) {
                    Object jdbcServiceRuntime = connection.getAttribute(objectName2, "JDBCServiceRuntime");
                    ObjectName[] jdbcDataSourceRuntimeMBeans = (ObjectName[]) connection.getAttribute((ObjectName) jdbcServiceRuntime, "JDBCDataSourceRuntimeMBeans");
                    String attributeNames[] = new String[] { "Name", "ActiveConnectionsCurrentCount", "ActiveConnectionsHighCount", "ConnectionDelayTime", "ConnectionsTotalCount", "Enabled", "FailuresToReconnectCount", "LeakedConnectionCount", "PrepStmtCacheAccessCount", "PrepStmtCacheCurrentSize", "PrepStmtCacheHitCount", "PrepStmtCacheMissCount", "State", "VersionJDBCDriver", "WaitingForConnectionCurrentCount", "WaitingForConnectionHighCount" };
                    for (ObjectName objectName3 : jdbcDataSourceRuntimeMBeans) {
                        Object attrValues[] = null;
                        attrValues = JmxUtil.getAttribute(connection, objectName3, attributeNames);
                        if (attrValues[0].toString().equals(jdbcName)) {
                            for (int i = 1; i < attrValues.length; i++) {
                                propValues[i - 1] = ResPropertyValue.createPropValue(attrValues[i].toString(), propMetas[i - 1]);

                            }
                            Object domainConfiguration = connection.getAttribute(service, "DomainConfiguration");
                            ObjectName[] systemResources = (ObjectName[]) connection.getAttribute((ObjectName) domainConfiguration, "SystemResources");
                            for (ObjectName objectName : systemResources) {
                                name = objectName.getKeyProperty("Name");
                                if (jdbcName.equals(name)) {
                                    Object jdbcResource = connection.getAttribute(objectName, "JDBCResource");
                                    Object jdbcConnectionPoolParams = connection.getAttribute((ObjectName) jdbcResource, "JDBCConnectionPoolParams");
                                    Object maxCapacity = connection.getAttribute((ObjectName) jdbcConnectionPoolParams, "MaxCapacity");
                                    propValues[15] = ResPropertyValue.createPropValue(maxCapacity.toString() == null ? "0" : maxCapacity.toString(), propMetas[15]);
                                }
                            }
                            //增加2个计算指标
                            if (attrValues[2] != null && attrValues[1] != null && !"".equals(attrValues[2].toString()) && !"".equals(attrValues[1].toString())) {
                                String activeConnectionsCurrentIdleCount = (Integer.valueOf(attrValues[2].toString()) - Integer.valueOf(attrValues[1].toString())) + "";
                                propValues[16] = ResPropertyValue.createPropValue(activeConnectionsCurrentIdleCount, propMetas[16]);
                            }
                            if (attrValues[10] != null && attrValues[11] != null && !"".equals(attrValues[10].toString()) && !"".equals(attrValues[11].toString())) {
                                int prepStmtCacheCount = Integer.valueOf(attrValues[10].toString()) + Integer.valueOf(attrValues[11].toString());
                                if (prepStmtCacheCount > 0) {
                                    String prepStmtCacheHitRate = (Integer.valueOf(attrValues[10].toString()) / prepStmtCacheCount) + "";
                                    propValues[17] = ResPropertyValue.createPropValue(prepStmtCacheHitRate, propMetas[17]);
                                } else {
                                    propValues[17] = ResPropertyValue.createPropValue("0", propMetas[17]);
                                }
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error("failed to collect by JdbcCollector", e);
            e.printStackTrace();
            throw new CollectorException(e);
        } finally {
            JmxUtil.closeConnector(connector);
        }
        propertyValueX.setValues(propValues);
        values.add(propertyValueX);
        return values;
    }

    @Override
    public String[] getParamMeta() {
        return new String[] { "ServerName", "JDBCName", "port" };
    }

    @Override
    public String[] getPropMeta() {
        // return new String[] { "ActiveConnectionsCurrentCount", "ActiveConnectionsHighCount", "ConnectionDelayTime", "ConnectionsTotalCount", "Enabled", "FailuresToReconnectCount", "LeakedConnectionCount", "PrepStmtCacheAccessCount", "PrepStmtCacheCurrentSize", "PrepStmtCacheHitCount", "PrepStmtCacheMissCount", "State", "VersionJDBCDriver", "WaitingForConnectionCurrentCount", "WaitingForConnectionHighCount", "MaxCapacity", "ActiveConnectionsCurrentIdleCount", "PrepStmtCacheHitRate" };
        return new String[] { "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$16", "$17", "$18" };
    }
}
